HBASE-30323 [RSGroup] Forward-port HBASE-22658 to branch-2 - #8547
HBASE-30323 [RSGroup] Forward-port HBASE-22658 to branch-2#8547Umeshkumar9414 wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
How about adding an IT test case for scenario when all servers in test RS group go down and fallback config is enabled (hbase.rsgroup.fallback.enable = true), then regions from test RS group do move to default RS group servers on calling RegionMover.unload().
| .map(JVMClusterUtil.RegionServerThread::getRegionServer) | ||
| .filter(rs -> rs.getServerName().equals(defaultSN)).findFirst().get(); | ||
| assertEquals(0, decommRS.getRegions(defaultTable).size(), | ||
| "Decommissioned default-group server must hold no regions after unload"); |
There was a problem hiding this comment.
Can we also please add assertion that default group regions don't land on test RS group servers?
There was a problem hiding this comment.
added the assertion in testUnloadDefaultGroupServerWithRSGroupEnabled
|
|
||
| /** A non-default group with one member must return only that member. */ | ||
| @Test | ||
| public void testNonDefaultGroupFiltersToMembers() throws Exception { |
There was a problem hiding this comment.
Can we add a test case where there is default RS group and some test RS group. And, assertion is that output of filter for default RS group should not have any server of test RS group. Please correct me if my understanding is wrong.
There was a problem hiding this comment.
added in testNonDefaultGroupFiltersToMembers
There is already test written for that, 'TestRSGroupsFallback'. |
e000187 to
856b438
Compare
|
The PR is ready to merge. We just need to co-ordinate when to merge this, I think it will be better to merge this after your fix on master branch is first merged and backported to branch-2 and others. Please let me know if there is any concern, I am fine either way. |
There was a problem hiding this comment.
Pull request overview
Updates RegionMover to respect RSGroup membership when selecting unload destinations on branch-2.
Changes:
- Queries RSGroup membership through the optional coprocessor RPC.
- Filters candidate RegionServers to the source server’s group.
- Relocates protobuf definitions and adds unit/integration tests.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
hbase-server/.../RegionMover.java |
Adds RSGroup lookup and destination filtering. |
hbase-server/.../TestRegionMoverFilterRSGroupServers.java |
Tests filtering behavior. |
hbase-rsgroup/.../TestRegionMoverWithRSGroupEnable.java |
Adds RSGroup-enabled integration tests. |
hbase-protocol/.../RSGroupAdmin.proto |
Makes RSGroup RPC definitions available through hbase-protocol. |
Suppressed comments (1)
hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRegionMoverWithRSGroupEnable.java:184
- This assertion claims to count this table's nine regions but counts every online region on the server. Any unrelated region left or later assigned there causes a false failure; assert against
getRegions(TABLE_NAME)as the isolation checks below already do.
assertEquals(9, onlineRS.getNumberOfOnlineRegions(),
"All 9 regions must be on the single remaining server in the test RSGroup");
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if (!resp.hasRSGroupInfo()) { | ||
| LOG.debug("No RSGroup found for {}:{} — server may not be registered or address form " | ||
| + "(hostname vs IP) may not match what the RS registered with", host, port); | ||
| return null; | ||
| } |
| Address decommission = rsservers.get(0); | ||
| Address online = rsservers.get(1); |
| * Unloading a server that is in the default RSGroup must still succeed end-to-end when RSGroups | ||
| * are enabled. The server's regions should be spread across all available servers (not filtered). |
|
@virajjasani Copilot found at least one issue (the first one) that should be resolved before merge. |
|
The move of We move RSGroups out of the separate module into core in HBase 3 and up, so there's that, but the way we hedged RSGroups in branch-2 puts everything else in This is not a dealbreaker, but there is an alternative that does not require it. Consider just using private RSGroupInfo getRSGroupInfo(String host, int port) throws IOException {
if (!RSGroupTableAccessor.isRSGroupsEnabled(conn)) {
return null;
}
Address addr = Address.fromParts(host, port);
for (RSGroupInfo info : RSGroupTableAccessor.getAllRSGroupInfo(conn)) {
if (info.containsServer(addr)) {
return info;
}
}
return null;
}I also like this approach better because the invocation of the coprocessor is brittle. It works today but any subclass or wrapper would break it, if someone is extending rsgroups and implementing their own enhanced coprocessors. Unlikely but not impossible. |
…lookup, deterministic test Switches RegionMover's RSGroup lookup from a coprocessor RPC (RSGroupAdminEndpoint) to reading the hbase:rsgroup table directly via RSGroupTableAccessor, as suggested by apurtell on PR apache#8547. This moves RSGroupAdmin.proto back to hbase-rsgroup (no longer needed in hbase-protocol) since hbase-server no longer talks to the coprocessor. Also addresses three Copilot review findings on the same PR: - getRSGroupInfo() now throws IOException instead of returning null when RSGroups are enabled but the server can't be matched to any group, so unloadRegions() doesn't silently fall back to treating every online server as a valid destination. - testUnloadRegionsRespectsRSGroup picks its decommission target by checking which rsservers member actually hosts a region, since moveTableRegionsToGroup() places regions via randomAssignment and rsservers.get(0) is not guaranteed to host anything. - Corrected the Javadoc on testUnloadDefaultGroupServerWithRSGroupEnabled to state that destinations are filtered to the default group, matching the test's actual isolation assertion.
|
Pushed 3dcff72 addressing the remaining review feedback: @apurtell's suggestion — switched Copilot findings:
Verified: |
Thanks a lot. @apurtell . I missed this. |
RegionMover.unloadRegions() previously picked destination servers from all online RegionServers regardless of RSGroup membership, potentially trying to move regions out of their assigned group during server decommission, althoug HMaster prevents it. This is a branch-2-compatible port of HBASE-22740. On master/branch-3 the fix used admin.getRSGroup() which is integrated directly into the Admin interface (via HBASE-22971). On branch-2 RSGroup remains an optional coprocessor (RSGroupAdminEndpoint), so we: 1. Check for RSGroupAdminEndpoint via getMasterCoprocessorNames() to skip the RSGroup path on clusters that do not use RSGroups. 2. Call getRSGroupInfoOfServer() via the RSGroupAdminService coprocessor RPC, using the unshaded protobuf service from hbase-protocol. 3. Filter the destination server list to only servers in the same RSGroup (filterRSGroupServers); filtering is always applied by membership — the DEFAULT_GROUP short-circuit that could leak regions across groups is removed. 4. Log a DEBUG message when hasRSGroupInfo()==false to aid diagnosis of hostname-vs-IP address-form mismatches (HBASE-27304). RSGroupAdmin.proto is moved from hbase-rsgroup to hbase-protocol so that hbase-server can use RSGroupAdminService without creating a circular dependency with hbase-rsgroup. Both modules depended on the same generated FQN; consolidating in hbase-protocol (which both already depend on) is best I could think of. Tests: - TestRegionMoverWithRSGroupEnable (hbase-rsgroup): 5-node mini cluster integration test with RSGroupAdminEndpoint enabled. Verifies that unloading a non-default-group server places all regions exclusively on the remaining server in that group (positive assertion) and that no default-group server receives any of those regions (isolation assertion). Also tests the guard path: unloading a default-group server succeeds end-to-end when RSGroups are enabled. - TestRegionMoverFilterRSGroupServers (hbase-server): unit tests for filterRSGroupServers() — default group returns full server list, non-default group filters to members only, no-match group returns empty. Co-authored-by: Claude Sonnet 4.6 <claude@anthropic.com>
…lookup, deterministic test Switches RegionMover's RSGroup lookup from a coprocessor RPC (RSGroupAdminEndpoint) to reading the hbase:rsgroup table directly via RSGroupTableAccessor, as suggested by apurtell on PR apache#8547. This moves RSGroupAdmin.proto back to hbase-rsgroup (no longer needed in hbase-protocol) since hbase-server no longer talks to the coprocessor. Also addresses three Copilot review findings on the same PR: - getRSGroupInfo() now throws IOException instead of returning null when RSGroups are enabled but the server can't be matched to any group, so unloadRegions() doesn't silently fall back to treating every online server as a valid destination. - testUnloadRegionsRespectsRSGroup picks its decommission target by checking which rsservers member actually hosts a region, since moveTableRegionsToGroup() places regions via randomAssignment and rsservers.get(0) is not guaranteed to host anything. - Corrected the Javadoc on testUnloadDefaultGroupServerWithRSGroupEnabled to state that destinations are filtered to the default group, matching the test's actual isolation assertion.
3dcff72 to
b06d77d
Compare
…rage Port the meta-RS exclusion and pre-unload precondition assertion from the master PR (apache#8552) version of testUnloadDefaultGroupServerWithRSGroupEnabled so both branches exercise the same scenario.
…vers Explains what each failed assertion means, and rewraps the class Javadoc to stay under the 100-char line limit.
|
I checked both are clean cherry-pick to 2.5 and 2.6. |
|
Triggered github workflow, please keep an eye if we get any non-flaky test failures |
RegionMover.unloadRegions() previously picked destination servers from all online RegionServers regardless of RSGroup membership, potentially trying to move regions out of their assigned group during server decommission, althoug HMaster prevents it.
This is a branch-2-compatible port of HBASE-22740. On master/branch-3 the fix used admin.getRSGroup() which is integrated directly into the Admin interface (via HBASE-22971). On branch-2 RSGroup remains an optional coprocessor module (hbase-rsgroup), so we:
Tests: